package bb.lanxing.util;

import com.github.mikephil.charting.utils.Utils;

import java.util.Calendar;

import bb.lanxing.App;
import bb.lanxing.model.database.User;
import bb.lanxing.model.database.Workout;

public class CalorieUtil {
    final static private String TAG = "CalorieUtil";
//    private static final int CALORIA_FACTOR = 1609;
    private static double mMBR = 1500.0d;

    public static int calcCalorieWithPower(float power, long duration) {
        Log.d(TAG, "calcCalorieWithPower power=" + power + ", duration=" + duration);
//        return (int) (((power > 0.0f ? (int) (power * ((float) duration)) : 0) / 4.184d) / 0.24d);
        int vCalorie = 0;
        if (power > 0.0f) {
            vCalorie = (int) (power * ((float) duration));
        }
        Log.d(TAG, "calcCalorieWithPower vCalorie=" + vCalorie);
        return vCalorie;
    }

    public static int calcTotalCalorie(int sport, double distance) {
        double d = 0.5d;
        if (sport == Workout.TYPE_WALKING) {
            d = 0.8d;
        } else if (sport == Workout.TYPE_RUNNING) {
            d = 1.0d;
        }
        Log.d(TAG, "calcTotalCalorie d=" + d + ", sport=" + sport + ", distance=" + distance);
        return (int) (distance * 70.0d * d);
    }

//    public static int calcTotalCalorie(Workout workout) {
//        return calcTotalCalorie(workout.getSport(), workout.getDistance());
//    }

    public static int calcRealtimeCalorieWithSpeed(double speed, long duration) {
        float f;
        float f2;
        User signinUser = App.getContext().getSigninUser();
        float weight = (signinUser == null || signinUser.getWeight() <= Utils.DOUBLE_EPSILON) ? 7500.0f : (float) ((signinUser.getWeight() + 10.0d) * 100.0d);
        Log.d(TAG, "calcRealtimeCalorieWithSpeed speed=" + speed + ", weight=" + weight + ", duration=" + duration);
        int i = (((int) (speed * 36.0d)) * 62137) / 10000;
        if (i < 1000) {
            f = (weight * 16090.0f) / 3600.0f;
            f2 = 400.0f;
        } else if (i < 1200) {
            f = (weight * 19308.0f) / 3600.0f;
            f2 = 320.0f;
        } else if (i < 1400) {
            f = (weight * 22526.0f) / 3600.0f;
            f2 = 280.0f;
        } else if (i < 1600) {
            f = (weight * 25744.0f) / 3600.0f;
            f2 = 256.0f;
        } else if (i < 2000) {
            f = (weight * 32180.0f) / 3600.0f;
            f2 = 270.0f;
        } else {
            f = (weight * 32180.0f) / 3600.0f;
            f2 = 200.0f;
        }
        Log.d(TAG, "calcRealtimeCalorieWithSpeed i=" + i + ", f=" + f + ", f2=" + f2);
        return (int) ((f / f2) * ((float) duration));
    }

    public static int calcRealtimeCalorieWithHR(int heartrate, long duration) {
        int i;
        float f;
        float f2;
        User signinUser = App.getContext().getSigninUser();
        Log.d(TAG, "calcRealtimeCalorieWithHR signinUser=" + signinUser);
        int i3 = 18;
        float f3 = 75.0f;
        if (signinUser != null) {
            if (signinUser.getWeight() > Utils.DOUBLE_EPSILON) {
                f3 = (float) (signinUser.getWeight() + 10.0d);
            }
            if (signinUser.getAge() > 0) {
                i3 = signinUser.getAge();
            }
            i = signinUser.getGender();
        } else {
            i = 1;
        }
        if (i == 1) {
            f = ((heartrate * 0.6309f) - 55.0969f) + (f3 * 0.1988f);
            f2 = 0.2017f;
        } else {
            f = ((heartrate * 0.4472f) - 20.4022f) + (f3 * 0.1263f);
            f2 = 0.074f;
        }
        return (int) (((f + (i3 * f2)) / 4.184f) * 60.0f * ((float) duration));
    }

    public static int getCurrentAge(long birthdateMillis) {
        Calendar dob = Calendar.getInstance();
        Calendar today = Calendar.getInstance();

        dob.setTimeInMillis(birthdateMillis);

        int age = today.get(Calendar.YEAR) - dob.get(Calendar.YEAR);

        // If the birth month and day is after the current month and day, subtract one year
        if (today.get(Calendar.MONTH) < dob.get(Calendar.MONTH) ||
                (today.get(Calendar.MONTH) == dob.get(Calendar.MONTH) &&
                        today.get(Calendar.DAY_OF_MONTH) < dob.get(Calendar.DAY_OF_MONTH))) {
            age--;
        }

        return age;
    }

    public static void updatePersonalBMR() {
        User signinUser = App.getContext().getSigninUser();
        if (signinUser != null) {
            double vWeight = signinUser.getWeight();
            double vHeight = signinUser.getHeight();
            int vGender = signinUser.getGender();
            long bd = signinUser.getBirthday();//get seconds, not milliseconds
            double vAge = getCurrentAge(bd * 1000);

            Log.d(TAG, "updatePersonalBMR from data: vWeight=" + vWeight
                    + ", vHeight=" + vHeight + ", vAge=" + vAge + ", vGender=" + vGender);
            if (vWeight > 150 || vWeight < 15) {
                vWeight = 60;
            }

            if (vHeight > 220 || vHeight < 100) {
                vHeight = 160;
            }

            if (vAge > 80 || vAge < 3) {
                vAge = 30;
            }
            Log.d(TAG, "updatePersonalBMR after adjust: vWeight=" + vWeight
                    + ", vHeight=" + vHeight + ", vAge=" + vAge + ", vGender=" + vGender);
            mMBR = 10 * vWeight + 6.25d * vHeight - 5 * vAge - (vGender == 1 ? -5 : 161);
            Log.d(TAG, "updatePersonalBMR user's mMBR=" + mMBR);
        } else {
            //default BMR, weight=60kg, height=170cm, age=30 years old
            mMBR = 10 * 60.0f + 6.25 * 170.0f - 5 * 30.0f + 5;
            Log.d(TAG, "updatePersonalBMR default mMBR=" + mMBR);
        }
    }

    private static double getPersonalBMR() {
        return mMBR;
    }

    public static double calcCalorieBMR(int sportType, double distance, long duration) {
        double vCalorie = 0.0d;
        double vBMR = getPersonalBMR();
        int vSpeed = (int) Math.round((distance / duration) * 3.6d);
        float vDurationInHours = duration / 3600.0f;
        float vMET = 3.0f;//default
        Log.d(TAG, "calcCalorieBMR default vSpeed=" + vSpeed + ", vDurationInHours=" + vDurationInHours);
        if (sportType == Workout.TYPE_WALKING) {
            if (vSpeed < 4) {
                vMET = 3.5f;
            } else if (vSpeed < 6) {
                vMET = 5.5f;
            }
        } else if (sportType == Workout.TYPE_RUNNING) {
            if (vSpeed < 8) {
                vMET = 8.2f;
            } else if (vSpeed < 12) {
                vMET = 12.7f;
            } else if (vSpeed < 16) {
                vMET = 16.8f;
            }
        } else if (sportType == Workout.TYPE_CYCLING) {
            if (vSpeed < 10) {
                vMET = 4.0f;
            } else if (vSpeed < 20) {
                vMET = 8.4f;
            } else if (vSpeed < 30) {
                vMET = 12.6f;
            }
        }
        vCalorie = vBMR * vMET / 24 * vDurationInHours * 1000;
        Log.d(TAG, "calcCalorieBMR default vMET=" + vMET + ", vCalorie=" + vCalorie);
        return vCalorie;
    }
}
